#pragma once
#include "DXAMLCommon.h"
#include "CXcpObjectBase.h"
#include "CXcpObjectAddRefPolicy.h"

class CPopupRoot;
class CUIElement;
class CRootVisual;
class CTransitionRoot;
class CContentControl;
class CLayoutManager;
class CPrintRoot;
class CInputManager;
class CFocusManager;
class CDependencyObject;

class VisualTree :
	public CXcpObjectBase<NoBaseClass,CXcpObjectAddRefPolicy>
{

public: 
	static HRESULT Create(CCoreServices * pCore, VisualTree * * ppVisualTree);
	CPopupRoot * GetPopupRoot();
	CRootVisual * GetRootVisual() const;
	CPrintRoot * GetPrintRoot();
	CTransitionRoot * GetTransitionRoot();
	CUIElement * GetPublicRootVisual() const;
	CContentControl * GetRootScrollViewer() const;
	CLayoutManager * GetLayoutManager() const;
	HRESULT ResetRoots(XBOOL * pReleasePopup);
	HRESULT Shutdown();
	HRESULT SetPublicRootVisual(CUIElement * pRoot, CContentControl * pRootScrollViewer);
	HRESULT SetAssociatedInputManager(CInputManager * pInputManager);
	HRESULT GetAssociatedInputManager(CInputManager * * ppInputManager);
	HRESULT SetAssociatedFocusManager(CFocusManager * pFocusManager);
	HRESULT GetAssociatedFocusManager(CFocusManager * * ppFocusManager);
	static CRootVisual * GetRootForElement(CDependencyObject * pObject);
	static CFocusManager * GetFocusManagerForElement(CDependencyObject * pObject);
	static CInputManager * GetInputManagerForElement(CDependencyObject * pObject);
	static CLayoutManager * GetLayoutManagerForElement(CDependencyObject * pObject);
	static HRESULT GetPopupRootForElement(CDependencyObject * pObject, CPopupRoot * * ppPopupRoot);
	static CTransitionRoot * GetTransitionRootForElement(CDependencyObject * pObject);

protected: 
	VisualTree(CCoreServices * pCore);
	virtual ~VisualTree();
private: 
	HRESULT Initialize();
	HRESULT EnsurePopupRoot();
	HRESULT EnsurePrintRoot();
	HRESULT EnsureTransitionRoot();
	HRESULT AddRoot(CUIElement * pRoot);
	HRESULT RemoveRoot(CUIElement * pRoot);
	HRESULT AddVisualRootToRootScrollViewer(CUIElement * pVisualRoot);
	HRESULT RemoveVisualRootFromRootScrollViewer(CUIElement * pVisualRoot);
	HRESULT AddRootScrollViewer(CContentControl * pRootScrollViewer);
	HRESULT RemoveRootScrollViewer(CContentControl * pRootScrollViewer);
	CUIElement * GetNamescopeOwnerForRoot(CUIElement * pRoot);
	CCoreServices * m_pCoreNoRef;
	CRootVisual * m_pRootVisual;
	CPopupRoot * m_pPopupRoot;
	CUIElement * m_pPublicRootVisual;
	CContentControl * m_pRootScrollViewer;
	CPrintRoot * m_pPrintRoot;
	CTransitionRoot * m_pTransitionRoot;
	CUIElement * m_pFullScreenOverlay;
	CInputManager * m_pInputManagerNoRef;
	CFocusManager * m_pFocusManagerNoRef;
	CLayoutManager * m_pLayoutManager;
	XBOOL m_bIsRootScrollViewerAddedToRoot;
};
